package lzyc.pointsManagement.business.points.service.impl;

import lzyc.pointsManagement.business.config.BizType;
import lzyc.pointsManagement.business.course.domain.CourseInfo;
import lzyc.pointsManagement.business.course.mapper.CourseInfoMapper;
import lzyc.pointsManagement.business.points.domain.PointsInfo;
import lzyc.pointsManagement.business.points.dto.RankViewModel;
import lzyc.pointsManagement.business.points.mapper.PointsInfoMapper;
import lzyc.pointsManagement.business.points.service.PointsInfoService;
import lzyc.pointsManagement.business.userdept.service.SysUserDeptService;
import lzyc.pointsManagement.common.core.domain.entity.SysUser;
import lzyc.pointsManagement.common.response.ResponseMessage;
import lzyc.pointsManagement.common.response.ResponseMessageUtility;
import lzyc.pointsManagement.common.utils.ShiroUtils;
import lzyc.pointsManagement.common.utils.StringUtils;
import lzyc.pointsManagement.common.utils.uuid.IdUtils;
import lzyc.pointsManagement.framework.web.domain.server.Sys;
import lzyc.pointsManagement.system.service.ISysUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * (PointsInfo)表服务实现类
 *
 * @author yangyang
 * @since 2024-03-10 17:11:34
 */
@Service("pointsInfoService")
public class PointsInfoServiceImpl implements PointsInfoService {
    @Resource
    private PointsInfoMapper pointsInfoMapper;

    @Resource
    private CourseInfoMapper courseInfoMapper;

    @Resource
    ISysUserService iSysUserService;

    /**
     * 通过ID查询单条数据
     *
     * @param pointsId 主键
     * @return 实例对象
     */
    @Override
    public PointsInfo queryById(String pointsId) {
        return this.pointsInfoMapper.queryById(pointsId);
    }

    @Override
    public PointsInfo queryByProjectIdAndUserId(String projectId, String userId) {
        return this.pointsInfoMapper.queryByProjectIdAndUserId(projectId, userId);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Override
    public List<PointsInfo> queryAllByLimit(int offset, int limit) {
        return this.pointsInfoMapper.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param pointsInfo 实例对象
     * @return 实例对象
     */
    @Override
    public PointsInfo insert(PointsInfo pointsInfo) {
        if (StringUtils.isEmpty(pointsInfo.getPointsId())) {
            pointsInfo.setPointsId(IdUtils.randomUUID());
        }
        this.pointsInfoMapper.insert(pointsInfo);
        return pointsInfo;
    }

    /**
     * 修改数据
     *
     * @param pointsInfo 实例对象
     * @return 实例对象
     */
    @Override
    public PointsInfo update(PointsInfo pointsInfo) {
        this.pointsInfoMapper.update(pointsInfo);
        return this.queryById(pointsInfo.getPointsId());
    }

    /**
     * 通过主键删除数据
     *
     * @param pointsId 主键
     * @return 是否成功
     */
    @Override
    public int deleteById(String[] pointsId) {
        return this.pointsInfoMapper.deleteById(pointsId);
    }

    @Override
    public int deleteByProjectId(String[] projectIds) {
        return this.pointsInfoMapper.deleteByProjectId(projectIds);
    }

    @Override
    public ResponseMessage addPointsFromCourse(String courseId) {
        CourseInfo courseInfo = courseInfoMapper.selectCourseInfoById(courseId);
        if (courseInfo == null) {
            return ResponseMessageUtility.createError("课程不存在");
        }
        PointsInfo pointsInfo = new PointsInfo();
        pointsInfo.setPointsUserId(ShiroUtils.getLoginName());
        pointsInfo.setPointsId(IdUtils.randomUUID());
        pointsInfo.setPointsDate(new Date());
        pointsInfo.setProjectId(courseInfo.getId());
        int score = courseInfo.getScore();
        if (score > 0) {
            pointsInfo.setType(BizType.Course.getCode());
        } else {
            pointsInfo.setType(BizType.StudyGarden.getCode());
        }
        pointsInfo.setScore(score);
        if (!checkPointExist(pointsInfo.getProjectId(), pointsInfo.getPointsUserId())) {
            pointsInfoMapper.insert(pointsInfo);
        }
        return ResponseMessageUtility.createSuccess();
    }

    @Override
    public ResponseMessage getPersonalMonthPoints(String userId) {
        ResponseMessage responseMessage;
        List<PointsInfo> pointsInfos = pointsInfoMapper.queryByUserId(userId);
        if (pointsInfos != null && !pointsInfos.isEmpty()) {
            // 获取当前日期并转换为LocalDate
            LocalDate currentDate = LocalDate.now();

            // 获取当前月的第一天和最后一天
            LocalDate firstDayOfMonth = currentDate.withDayOfMonth(1);
            LocalDate lastDayOfMonth = currentDate.with(java.time.temporal.TemporalAdjusters.lastDayOfMonth());

            // 使用Stream API过滤出当前月内的数据
            List<PointsInfo> currentMonthData = pointsInfos.stream().filter(data -> {
                // 将Date转换为LocalDate
                LocalDate dataDate = data.getPointsDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                // 检查日期是否在当前月内
                return !dataDate.isBefore(firstDayOfMonth) && !dataDate.isAfter(lastDayOfMonth);
            }).collect(Collectors.toList());
            if (!currentMonthData.isEmpty()) {
                int sum = currentMonthData.stream().map(PointsInfo::getScore).reduce(0, Integer::sum);
                responseMessage = ResponseMessageUtility.createSuccess();
                responseMessage.setData(sum);
            } else {
                responseMessage = ResponseMessageUtility.createError("用户没有积分");
            }

        } else {
            responseMessage = ResponseMessageUtility.createError("用户没有积分");
        }
        return responseMessage;
    }

    @Override
    public ResponseMessage getPersonalPoints(String userId) {
        ResponseMessage responseMessage;
        List<PointsInfo> pointsInfos = pointsInfoMapper.queryByUserId(userId);
        if (pointsInfos != null && !pointsInfos.isEmpty()) {
            int sum = pointsInfos.stream().map(PointsInfo::getScore).reduce(0, Integer::sum);
            responseMessage = ResponseMessageUtility.createSuccess();
            responseMessage.setData(sum);
        } else {
            responseMessage = ResponseMessageUtility.createError("用户没有积分");
        }
        return responseMessage;
    }

    @Override
    public ResponseMessage getPointsRank() {
        ResponseMessage responseMessage = ResponseMessageUtility.createSuccess();
        List<PointsInfo> pointsInfoList = pointsInfoMapper.queryAll(new PointsInfo());
        Map<String, Integer> totalScoreMap = pointsInfoList.stream()
                .collect(Collectors.groupingBy(PointsInfo::getPointsUserId, Collectors.summingInt(PointsInfo::getScore)));

        List<RankViewModel> rankList = new ArrayList<>();
        List<Map.Entry<String, Integer>> entries = new ArrayList<>(totalScoreMap.entrySet());
        // 根据总积分降序排序
        entries.sort((e1, e2) -> Integer.compare(e2.getValue(), e1.getValue()));

        // 分配排名
        for (int i = 0; i < entries.size(); i++) {
            Map.Entry<String, Integer> entry = entries.get(i);
            SysUser user = iSysUserService.selectUserByLoginName(entry.getKey());
            if (user == null) {
                continue;
            }
            RankViewModel rank = new RankViewModel();
            rank.setPointRank(String.valueOf(i + 1));
            rank.setUserInfo(user);
            rank.setScore(entry.getValue());
            rankList.add(rank);
        }
        responseMessage.setData(rankList);
        return responseMessage;
    }

    @Override
    public ResponseMessage getMonthPointsRank() {
        ResponseMessage responseMessage;
        List<PointsInfo> pointsInfoList = pointsInfoMapper.queryAll(new PointsInfo());
        if (pointsInfoList != null && !pointsInfoList.isEmpty()) {
            List<RankViewModel> rankList = getMonthRankViewModels(pointsInfoList);
            responseMessage = ResponseMessageUtility.createSuccess();
            responseMessage.setData(rankList);
        } else {
            responseMessage = ResponseMessageUtility.createError("当前无排名。");
        }
        return responseMessage;
    }

    /**
     * 检查积分信息存在
     * 
     * @param projectId
     * @param pointsUserID
     * @return
     */
    @Override
    public boolean checkPointExist(String projectId, String pointsUserID) {
        return StringUtils.isNotEmpty(this.pointsInfoMapper.checkPointExist(projectId, pointsUserID));
    }

    @Override
    public ResponseMessage getGroupPointsRank() {
        ResponseMessage responseMessage = ResponseMessageUtility.createSuccess();
        List<PointsInfo> pointsInfoList = pointsInfoMapper.queryAll(new PointsInfo());
        Map<String, Integer> totalScoreMap = pointsInfoList.stream()
                .collect(Collectors.groupingBy(PointsInfo::getPointsUserId, Collectors.summingInt(PointsInfo::getScore)));

        List<RankViewModel> rankList = new ArrayList<>();
        List<Map.Entry<String, Integer>> entries = new ArrayList<>(totalScoreMap.entrySet());
        // 根据总积分降序排序
        entries.sort((e1, e2) -> Integer.compare(e2.getValue(), e1.getValue()));
        long groupId = ShiroUtils.getSysUser().getGroupId();
        // 分配排名
        for (int i = 0; i < entries.size(); i++) {
            Map.Entry<String, Integer> entry = entries.get(i);
            SysUser user = iSysUserService.selectUserByLoginName(entry.getKey());
            if (user == null) {
                continue;
            }
            if (user.getGroupId() == groupId) {
                RankViewModel rank = new RankViewModel();
                rank.setPointRank(String.valueOf(i + 1));
                rank.setUserInfo(user);
                rank.setScore(entry.getValue());
                rankList.add(rank);
            }
        }
        responseMessage.setData(rankList);
        return responseMessage;
    }

    private List<RankViewModel> getMonthRankViewModels(List<PointsInfo> pointsInfoList) {
        // 获取当前日期并转换为LocalDate
        LocalDate currentDate = LocalDate.now();
        // 获取当前月的第一天和最后一天
        LocalDate firstDayOfMonth = currentDate.withDayOfMonth(1);
        LocalDate lastDayOfMonth = currentDate.with(java.time.temporal.TemporalAdjusters.lastDayOfMonth());

        List<PointsInfo> currentMonthData = pointsInfoList.stream().filter(data -> {
            // 将Date转换为LocalDate
            LocalDate dataDate = data.getPointsDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            // 检查日期是否在当前月内
            return !dataDate.isBefore(firstDayOfMonth) && !dataDate.isAfter(lastDayOfMonth);
        }).collect(Collectors.toList());

        Map<String, Integer> totalScoreMap = currentMonthData.stream()
            .collect(Collectors.groupingBy(PointsInfo::getPointsUserId, Collectors.summingInt(PointsInfo::getScore)));

        List<RankViewModel> rankList = new ArrayList<>();
        List<Map.Entry<String, Integer>> entries = new ArrayList<>(totalScoreMap.entrySet());
        // 根据总积分降序排序
        entries.sort((e1, e2) -> Integer.compare(e2.getValue(), e1.getValue()));

        // 分配排名
        for (int i = 0; i < entries.size(); i++) {
            Map.Entry<String, Integer> entry = entries.get(i);
            SysUser user = iSysUserService.selectUserByLoginName(entry.getKey());
            if (user == null) {
                continue;
            }
            RankViewModel rank = new RankViewModel();
            rank.setPointRank(String.valueOf(i + 1));
            rank.setUserInfo(user);
            rank.setScore(entry.getValue());
            rankList.add(rank);
        }
        return rankList;
    }
}